{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# How to create custom callback handlers\n",
    "\n",
    ":::info Prerequisites\n",
    "\n",
    "This guide assumes familiarity with the following concepts:\n",
    "\n",
    "- [Callbacks](/docs/concepts/#callbacks)\n",
    "\n",
    ":::\n",
    "\n",
    "LangChain has some built-in callback handlers, but you will often want to create your own handlers with custom logic.\n",
    "\n",
    "To create a custom callback handler, we need to determine the [event(s)](https://api.js.langchain.com/interfaces/langchain_core_callbacks_base.CallbackHandlerMethods.html) we want our callback handler to handle as well as what we want our callback handler to do when the event is triggered. Then all we need to do is attach the callback handler to the object, for example via [the constructor](/docs/how_to/callbacks_constructor) or [at runtime](/docs/how_to/callbacks_runtime).\n",
    "\n",
    "An easy way to construct a custom callback handler is to initialize it as an object whose keys are functions with names matching the events we want to handle. Here's an example that only handles the start of a chat model and streamed tokens from the model run:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Chat model start: {\n",
      "  lc: 1,\n",
      "  type: \"constructor\",\n",
      "  id: [ \"langchain\", \"chat_models\", \"anthropic\", \"ChatAnthropic\" ],\n",
      "  kwargs: {\n",
      "    callbacks: undefined,\n",
      "    model: \"claude-3-sonnet-20240229\",\n",
      "    verbose: undefined,\n",
      "    anthropic_api_key: { lc: 1, type: \"secret\", id: [ \"ANTHROPIC_API_KEY\" ] },\n",
      "    api_key: { lc: 1, type: \"secret\", id: [ \"ANTHROPIC_API_KEY\" ] }\n",
      "  }\n",
      "} [\n",
      "  [\n",
      "    HumanMessage {\n",
      "      lc_serializable: true,\n",
      "      lc_kwargs: {\n",
      "        content: \"What is 1 + 2?\",\n",
      "        additional_kwargs: {},\n",
      "        response_metadata: {}\n",
      "      },\n",
      "      lc_namespace: [ \"langchain_core\", \"messages\" ],\n",
      "      content: \"What is 1 + 2?\",\n",
      "      name: undefined,\n",
      "      additional_kwargs: {},\n",
      "      response_metadata: {}\n",
      "    }\n",
      "  ]\n",
      "] b6e3b7ad-c602-4cef-9652-d51781a657b7\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Chat model new token The\n",
      "Chat model new token  sum\n",
      "Chat model new token  of\n",
      "Chat model new token  \n",
      "Chat model new token 1\n",
      "Chat model new token  \n",
      "Chat model new token an\n",
      "Chat model new token d \n",
      "Chat model new token 2\n",
      "Chat model new token  \n",
      "Chat model new token is\n",
      "Chat model new token  \n",
      "Chat model new token 3\n",
      "Chat model new token .\n"
     ]
    }
   ],
   "source": [
    "import { ChatPromptTemplate } from \"@langchain/core/prompts\";\n",
    "import { ChatAnthropic } from \"@langchain/anthropic\";\n",
    "\n",
    "const prompt = ChatPromptTemplate.fromTemplate(`What is 1 + {number}?`);\n",
    "const model = new ChatAnthropic({\n",
    "  model: \"claude-3-sonnet-20240229\",\n",
    "});\n",
    "\n",
    "const chain = prompt.pipe(model);\n",
    "\n",
    "const customHandler = {\n",
    "  handleChatModelStart: async (llm, inputMessages, runId) => {\n",
    "    console.log(\"Chat model start:\", llm, inputMessages, runId)\n",
    "  },\n",
    "  handleLLMNewToken: async (token) => {\n",
    "    console.log(\"Chat model new token\", token);\n",
    "  }\n",
    "};\n",
    "\n",
    "const stream = await chain.stream({ number: \"2\" }, { callbacks: [customHandler] });\n",
    "\n",
    "for await (const _ of stream) {\n",
    "  // Just consume the stream so the callbacks run\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "You can see [this reference page](https://api.js.langchain.com/interfaces/langchain_core_callbacks_base.CallbackHandlerMethods.html) for a list of events you can handle. Note that the `handleChain*` events run for most LCEL runnables.\n",
    "\n",
    "## Next steps\n",
    "\n",
    "You've now learned how to create your own custom callback handlers.\n",
    "\n",
    "Next, check out the other how-to guides in this section, such as [how to background callbacks](/docs/how_to/callbacks_backgrounding)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Deno",
   "language": "typescript",
   "name": "deno"
  },
  "language_info": {
   "file_extension": ".ts",
   "mimetype": "text/x.typescript",
   "name": "typescript",
   "nb_converter": "script",
   "pygments_lexer": "typescript",
   "version": "5.3.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
